package carassius.BLL;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.GregorianCalendar;

/**
 *
 * @author siebz0r
 */
public class GregorianCalendarWithEvents
		extends GregorianCalendar
{
	private PropertyChangeSupport _propertyChangeSupport;

	public GregorianCalendarWithEvents()
	{
		this(new GregorianCalendar());
	}

	public GregorianCalendarWithEvents(GregorianCalendar cal)
	{
		this(cal.get(GregorianCalendar.YEAR), cal.get(GregorianCalendar.MONTH), cal.get(GregorianCalendar.DATE));
	}

	public GregorianCalendarWithEvents(int year, int month, int dayOfMonth)
	{
		super(year, month, dayOfMonth);
	}

	private String translateFieldToName(int field)
	{
		switch (field)
		{
			case DATE:
				return "day";
			case MONTH:
				return "month";
			case YEAR:
				return "year";
			case WEEK_OF_YEAR:
				return "weekOfYear";
			default:
				return null;
		}
	}

	@Override
	public void set(int field, int value)
	{
		int oldVal = get(field);
		if (oldVal != value)
		{
			String propertyName = translateFieldToName(field);
			if (propertyName != null)
			{
				super.set(field, value);
				firePropertyChange(propertyName, oldVal, value);
			}
			else
			{
				super.set(field, value);
			}
		}
	}

	@Override
	public void setFirstDayOfWeek(int value)
	{
		int oldVal = getFirstDayOfWeek();
		if (oldVal != value)
		{
			super.setFirstDayOfWeek(value);
			firePropertyChange("firstDayOfWeek", oldVal, value);
		}
	}

	@Override
	public void add(int field, int amount)
	{
		String propertyName = translateFieldToName(field);
		if (propertyName != null)
		{
			int oldVal = get(field);
			super.add(field, amount);
			firePropertyChange(propertyName, oldVal, get(field));
		}
		else
		{
			super.add(field, amount);
		}
	}

	@Override
	public void roll(int field, boolean up)
	{
		String propertyName = translateFieldToName(field);
		if (propertyName != null)
		{
			int oldVal = get(field);
			super.roll(field, up);
			firePropertyChange(propertyName, oldVal, get(field));
		}
		else
		{
			super.roll(field, up);
		}
	}

	@Override
	public void roll(int field, int amount)
	{
		String propertyName = translateFieldToName(field);
		if (propertyName != null)
		{
			int oldVal = get(field);
			super.roll(field, amount);
			firePropertyChange(propertyName, oldVal, oldVal);
		}
		else
		{
			super.roll(field, amount);
		}
	}

	private void firePropertyChange(String propertyName, int oldValue,
									int newValue)
	{
		if (_propertyChangeSupport != null)
		{
			_propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
		}
	}

	private void firePropertyChange(String propertyName, boolean oldValue,
									boolean newValue)
	{
		if (_propertyChangeSupport != null)
		{
			_propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
		}
	}

	private void firePropertyChange(String propertyName, Object oldValue,
									Object newValue)
	{
		if (_propertyChangeSupport != null)
		{
			_propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
		}
	}

	private void firePropertyChange(PropertyChangeEvent evt)
	{
		if (_propertyChangeSupport != null)
		{
			_propertyChangeSupport.firePropertyChange(evt);
		}
	}

	public void addPropertyChangeListener(PropertyChangeListener listener)
	{
		if (_propertyChangeSupport == null)
		{
			_propertyChangeSupport = new PropertyChangeSupport(this);
		}
		_propertyChangeSupport.addPropertyChangeListener(listener);

	}

	public void addPropertyChangeListener(String propertyName,
										  PropertyChangeListener listener)
	{
		if (_propertyChangeSupport == null)
		{
			_propertyChangeSupport = new PropertyChangeSupport(this);
		}
		_propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
	}

	public void removePropertyChangeListener(PropertyChangeListener listener)
	{
		if (_propertyChangeSupport != null)
		{
			_propertyChangeSupport.removePropertyChangeListener(listener);
		}
	}

	public void removePropertyChangeListener(String propertyName,
											 PropertyChangeListener listener)
	{
		if (_propertyChangeSupport != null)
		{
			_propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
		}
	}
}
